import { findAppByRoute } from "../utils/index.js";
import { getMainLifeCycle } from '../const/mainLifeCycle.js';
import { loadHtml } from "../loader/index.js";

export const lifeCycle = async () => {
  // 获取到上一个子应用
  // 为什么要获取到上一个子应用，是因为我们要获取到上一个子应用里我们要执行它的unmount，
  // 我们需要先将上一个子应用完全的卸载掉，那么之后我们在获取到要跳转到的子应用执行对应的子应用生命周期
  const prevApp = findAppByRoute(window.__ORIGIN_APP__);

  // 获取到要跳转的子应用
  const nextApp = findAppByRoute(window.__CURRENT_SUB_APP__);
  // console.log(prevApp, nextApp);
  if (!nextApp) {
    return;
  }
  if (prevApp && prevApp.unmount) {
    if(prevApp.proxy){
      prevApp.proxy.inactive(); // 将沙箱销毁
    }
    await destroyed(prevApp); // 让我们上一个 app 销毁
  }
  // 然后我们在执行它下一个 app 的 beforeLoad 和 mounted 的内容
  const app = await beforeLoad(nextApp);
  await mounted(app);
};

// 微前端的生命周期
export const beforeLoad = async (app) => {
  await runMainLifeCycle('beforeLoad');
  app && app.beforeLoad && app.beforeLoad();

  // 获取到我们子应用所有的显示的内容
  const subApp = await loadHtml(app); // 通过请求来获取我们子应用的内容，那么由于我们获取子应用的内容它是一个网络请求的方式，所以这里呢我们来使用 await 做一个等待
  subApp && subApp.beforeLoad && subApp.beforeLoad();

  return subApp;
};

export const mounted = async (app) => {
  app && app.mount && app.mount({
    appInfo: app.appInfo,
    entry: app.entry
  });
  await runMainLifeCycle('mounted');
};

export const destroyed = async (app) => {
  app && app.unmount && app.unmount();
  // 对应的执行一下主应用里的生命周期
  await runMainLifeCycle('destroyed');
};

// 执行我们主应用的生命周期内容
export const runMainLifeCycle = async (type) => {
  const mainLife = getMainLifeCycle();
  // 需要等到它 mainLife[type].map(async item => await item()) 全部执行完成
  // 我们需要等到 Promise.all 当前生命周期里所有的方法都执行完成了
  // 生命周期里的方法都有可能是一个异步的方法，所以说这里我们使用 async 和 await 来等待它们执行成功
  await Promise.all(mainLife[type].map(async item => await item()));
}
